객체 심볼

심볼형#

자바 스크립트 객체 프로퍼티의 자료형 : 문자형, 심볼형

심볼 Symbol#

Symbol() 유일한 식별자를 만들때 사용함.

// id는 새로운 심볼이 됩니다.
let id = Symbol();

심볼이름 붙이기#

  • 디버깅시 유용함.
// 심볼 id에는 "id"라는 설명이 붙습니다.
let id = Symbol("id");
  • 이름을 붙여도 심볼이 반환하는 값은 항상 다르다.
let id1 = Symbol("id");
let id2 = Symbol("id");
alert(id1 == id2); // false

심볼의 자동형변환#

  • 심볼의 암시적 형변환 X
let id = Symbol("id");
alert(id); // TypeError: Cannot convert a Symbol value to a string
  • 자바스크립트: 문자형으로 암시적 형변환이 비교적 자유로움

-> alert 함수가 거의 모든 값을 인자로 받을 수 있다.

  • 심볼을 alert 로 출력하는 방법
    • .toString() 메서드 호출
    • symbo.description 프로퍼티 사용
      let id = Symbol("id");
      alert(id.toString()); // Symbol(id)가 얼럿 창에 출력됨
      alert(id.description); // id

심볼을 이용한 숨김 프로퍼티#

숨김 프로퍼티

  • 외부 코드에서 접근이 불가능하고 값도 덮어쓸 수 없는 프로퍼티
  • 서드 파티 코드는 일반적으로 접근할 수 없다.
  • 심볼을 사용하면 서드파티 모르게 user 에 식별자를 부여할 수 있다.
let user = { // 서드파티 코드에서 가져온 객체
name: "John"
};
let id = Symbol("id");
user[id] = 1;
alert( user[id] ); // 심볼을 키로 사용해 데이터에 접근할 수 있습니다.

만약 제3의 스크립트가 우리 스크립트와 동일하게 문자열 "id"를 이용해 식별자를 만들었다면

let user = { name: "John" };
// 문자열 "id"를 사용해 식별자를 만들었습니다.
user.id = "스크립트 id 값";
user.id = "제3 스크립트 id 값"
// 의도치 않게 값이 덮어 쓰여서 우리가 만든 식별자는 무의미해집니다.

사실상 심볼을 완전히 숨기는 방법은 없다.

  • Object.getOwnPropertySymbols(obj) 모든 심볼을 볼 수 있다.
  • Reflect.ownKeys(obj) 심볼형 키를 포함한 객체의 모든 키를 반환한다.

객체 리터럴에서의 심볼#

let id = Symbol("id");
let user = {
name: "John",
[id]: 123 // "id": 123은 안됨
};

심볼은 for…in 에서 배제됨#

let id = Symbol("id");
let user = {
name: "John",
age: 30,
[id]: 123
};
for (let key in user) alert(key); // name과 age만 출력되고, 심볼은 출력되지 않습니다.
// 심볼로 직접 접근하면 잘 작동합니다.
alert( "직접 접근한 값: " + user[id] );

Object.assign 은 키가 심볼인 프로퍼티도 복사#

let id = Symbol("id");
let user = {
[id]: 123
};
let clone = Object.assign({}, user);
alert( clone[id] ); // 123

전역 심볼 레지스트리 (global symbol registry)#

전역 심볼 레지스트리 안에 심볼을 만들고 해당 심볼에 접근하면 항상 동일한 심볼을 반환해준다.

Symbol.for(key) 로 접근 / 생성

  • 호출
    • 조건에 맞는 심볼 검사
    • 없다면 새로운 Symbol(key) 를 만들고 레지스트리 안에 저장함.
    • 이름이 key 인 심볼 반환
// 전역 레지스트리에서 심볼을 읽습니다.
let id = Symbol.for("id"); // 심볼이 존재하지 않으면 새로운 심볼을 만듭니다.
// 동일한 이름을 이용해 심볼을 다시 읽습니다(좀 더 멀리 떨어진 코드에서도 가능합니다).
let idAgain = Symbol.for("id");
// 두 심볼은 같습니다.
alert( id === idAgain ); // true

전역 심볼#

  • 전역 심볼 레지스트리 안에 있는 심볼
  • 어플리케이션에서 광범위 하게 사용해야 하는 심볼

Symbol.keyFor(sym)#

전역 심볼 레지스트리에서 심볼으로 이름을 얻는 메서드

  • 찾지 못하면 undefined 반환

  • Symbol.for(key) 와 반대됨

// 이름을 이용해 심볼을 찾음
let sym = Symbol.for("name");
let sym2 = Symbol.for("id");
// 심볼을 이용해 이름을 얻음
alert( Symbol.keyFor(sym) ); // name
alert( Symbol.keyFor(sym2) ); // id
  • 일반 심볼에서 이름을 얻고 싶을 땐 description 프로퍼티를 사용한다.
let globalSymbol = Symbol.for("name");
let localSymbol = Symbol("name");
alert( Symbol.keyFor(globalSymbol) ); // name, 전역 심볼
alert( Symbol.keyFor(localSymbol) ); // undefined, 전역 심볼이 아님
alert( localSymbol.description ); // name

시스템 심볼#

자바스크립트 내부에서 사용되는 심볼

  • 내장 메서드 등의 기본 동작을 변경할 수 있다.
  • iterable 객체 -> Symbol.iterator
  • 객체를 원시형으로 변환 -> Symbol.toPrimitive

잘 알려진 심볼 well-known-symbols#

  • Symbol.hasInstance
  • Symbol.isConcatSpreadable
  • Symbol.iterator
  • Symbol.toPrimitive
  • etc

더 보면 좋은 글#

Last updated on